<template>
  <div class="h-full flex flex-col bg-white">
    <div class="flex items-center justify-between px-4 py-2 border-b border-gray-100">
      <!-- 左侧：批量操作 -->
      <div class="flex items-center gap-2">
        <el-checkbox
          v-if="breakpoints.length > 0"
          :indeterminate="isIndeterminate"
          v-model="checkAll"
          @change="handleCheckAllChange"
        >
          全选
        </el-checkbox>
        <el-dropdown
          v-if="selectedBreakpoints.length > 0"
          trigger="click"
          @command="handleBatchCommand"
        >
          <el-button type="text" size="small" class="!text-gray-600">
            批量操作 ({{ selectedBreakpoints.length }}) <i class="el-icon-arrow-down el-icon--right"></i>
          </el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="enable">启用选中</el-dropdown-item>
            <el-dropdown-item command="disable">禁用选中</el-dropdown-item>
            <el-dropdown-item command="delete" divided>删除选中</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>

      <!-- 右侧：操作按钮 -->
      <div class="flex items-center gap-2">
        <el-dropdown
          v-if="breakpoints.length > 0"
          trigger="click"
          @command="handleMoreCommand"
        >
          <el-button type="text" size="small" class="!text-gray-600">
            更多 <i class="el-icon-arrow-down el-icon--right"></i>
          </el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="export">
              <i class="el-icon-download"></i> 导出断点
            </el-dropdown-item>
            <el-dropdown-item command="import">
              <i class="el-icon-upload2"></i> 导入断点
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-button
          v-else
          type="text"
          icon="el-icon-upload2"
          size="small"
          class="!text-gray-600"
          @click="handleImportBreakpoints"
        >
          导入断点
        </el-button>
        <el-button
          type="text"
          icon="el-icon-plus"
          size="small"
          class="!text-primary-500 hover:!text-primary-600"
          :disabled="!canAddOrEdit"
          @click="showAddDialog"
        >
          添加断点
        </el-button>
      </div>
    </div>

    <!-- 隐藏的文件输入框用于导入 -->
    <input
      ref="fileInput"
      type="file"
      accept=".json"
      style="display: none"
      @change="handleFileChange"
    />

    <!-- 搜索和过滤栏 -->
    <div v-if="breakpoints.length > 0" class="px-4 py-2 border-b border-gray-100 bg-gray-50">
      <div class="flex gap-2">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索断点（文件名、路径或条件）"
          size="small"
          clearable
          prefix-icon="el-icon-search"
          class="flex-1"
        >
          <el-select
            v-model="filterEnabled"
            slot="append"
            placeholder="筛选"
            style="width: 100px"
          >
            <el-option label="全部" value="all"></el-option>
            <el-option label="已启用" value="enabled"></el-option>
            <el-option label="已禁用" value="disabled"></el-option>
          </el-select>
        </el-input>
        <!-- 分组/列表视图切换 -->
        <el-button-group>
          <el-button
            :type="viewMode === 'grouped' ? 'primary' : ''"
            size="small"
            icon="el-icon-folder"
            @click="viewMode = 'grouped'"
            title="按文件分组"
          ></el-button>
          <el-button
            :type="viewMode === 'list' ? 'primary' : ''"
            size="small"
            icon="el-icon-menu"
            @click="viewMode = 'list'"
            title="列表视图"
          ></el-button>
        </el-button-group>
      </div>
    </div>

    <div class="flex-1 overflow-y-auto py-1">
      <div
        v-if="breakpoints.length === 0"
        class="flex flex-col items-center justify-center h-48 text-gray-400"
      >
        <i class="el-icon-info text-5xl mb-2 opacity-50"></i>
        <p class="text-sm m-0">暂无断点</p>
      </div>

      <!-- 没有匹配结果的提示 -->
      <div
        v-else-if="filteredBreakpoints.length === 0"
        class="flex flex-col items-center justify-center h-48 text-gray-400"
      >
        <i class="el-icon-search text-5xl mb-2 opacity-50"></i>
        <p class="text-sm m-0">没有匹配的断点</p>
        <p class="text-xs m-0 mt-1">尝试修改搜索条件或过滤器</p>
      </div>

      <!-- 分组视图 -->
      <div v-else-if="viewMode === 'grouped'">
        <div
          v-for="group in groupedBreakpoints"
          :key="group.file"
          class="mb-1"
        >
          <!-- 分组标题 -->
          <div
            class="flex items-center px-4 py-2 bg-gray-100 cursor-pointer hover:bg-gray-200 transition-colors sticky top-0 z-10"
            @click="toggleGroup(group.file)"
          >
            <i
              :class="isGroupExpanded(group.file) ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"
              class="text-gray-600 mr-2"
            ></i>
            <i class="el-icon-folder text-yellow-600 mr-2"></i>
            <span class="flex-1 text-sm font-medium text-gray-800 truncate" :title="group.file">
              {{ formatFileName(group.file) }}
            </span>
            <div class="flex items-center gap-2 ml-2">
              <el-tag size="mini" type="info">{{ group.total }}</el-tag>
              <el-tag v-if="group.enabled > 0" size="mini" type="success">{{ group.enabled }} 启用</el-tag>
              <el-tag v-if="group.disabled > 0" size="mini" type="info">{{ group.disabled }} 禁用</el-tag>
              <!-- 分组级别操作按钮 -->
              <el-dropdown
                trigger="click"
                @command="handleGroupCommand($event, group)"
                @click.native.stop
              >
                <el-button type="text" size="mini" class="!text-gray-500 hover:!text-gray-700">
                  <i class="el-icon-more"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="enable-all">启用全部</el-dropdown-item>
                  <el-dropdown-item command="disable-all">禁用全部</el-dropdown-item>
                  <el-dropdown-item command="delete-all" divided>删除全部</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </div>
          </div>
          <!-- 分组内的断点列表 -->
          <div v-show="isGroupExpanded(group.file)">
            <div
              v-for="bp in group.breakpoints"
              :key="bp.id"
              class="flex items-center px-4 py-2.5 pl-12 transition-colors hover:bg-gray-50 group"
              :class="{ 'opacity-50': bp.enabled === false }"
            >
              <!-- 选择框（批量操作用） - 方形，灰色边框 -->
              <el-checkbox
                :value="selectedBreakpoints.includes(bp.id)"
                @change="handleSelectChange(bp.id, $event)"
                class="mr-3 batch-checkbox"
                title="选择此断点"
              ></el-checkbox>

              <div
                class="text-base mr-2.5"
                :class="bp.enabled === false ? 'text-gray-400' : 'text-red-600'"
              >
                <i :class="bp.condition ? 'el-icon-s-flag' : 'el-icon-location-outline'"></i>
              </div>
              <div class="flex-1 overflow-hidden cursor-pointer">
                <div class="text-sm mb-1"
                  :class="bp.enabled === false ? 'text-gray-400 line-through' : 'text-gray-800'"
                >
                  行 {{ bp.line }}
                </div>
                <div v-if="bp.condition" class="text-xs text-orange-600 mb-1">
                  <i class="el-icon-warning-outline"></i> 条件: {{ bp.condition }}
                </div>
                <div v-if="bp.hitCondition" class="text-xs text-purple-600 mb-1">
                  <i class="el-icon-data-line"></i> 命中: {{ bp.hitCondition }}
                </div>
                <!-- 命中统计 -->
                <div v-if="bp.hitCount > 0" class="text-xs text-blue-600 mt-1">
                  <i class="el-icon-aim"></i> 已命中 {{ bp.hitCount }} 次
                </div>
              </div>
              <div class="ml-2.5 flex items-center gap-2">
                <!-- 启用/禁用开关 -->
                <el-switch
                  :value="bp.enabled !== false"
                  @change="handleToggle(bp.id)"
                  :width="36"
                  active-color="#67C23A"
                  inactive-color="#DCDFE6"
                  title="启用/禁用断点"
                  class="opacity-0 group-hover:opacity-100 transition-opacity"
                ></el-switch>
                <el-button
                  type="text"
                  icon="el-icon-edit"
                  size="small"
                  class="!text-gray-400 hover:!text-blue-600 opacity-0 group-hover:opacity-100 transition-opacity"
                  :disabled="!canAddOrEdit"
                  @click="handleEdit(bp)"
                ></el-button>
                <el-button
                  type="text"
                  icon="el-icon-delete"
                  size="small"
                  class="!text-gray-400 hover:!text-red-600 opacity-0 group-hover:opacity-100 transition-opacity"
                  @click="handleRemove(bp.id)"
                ></el-button>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 列表视图 -->
      <div v-else>
        <div
          v-for="bp in filteredBreakpoints"
          :key="bp.id"
          class="flex items-center px-4 py-2.5 transition-colors hover:bg-gray-50 group"
          :class="{ 'opacity-50': bp.enabled === false }"
        >
          <!-- 选择框（批量操作用） - 方形，灰色边框 -->
          <el-checkbox
            :value="selectedBreakpoints.includes(bp.id)"
            @change="handleSelectChange(bp.id, $event)"
            class="mr-3 batch-checkbox"
            title="选择此断点"
          ></el-checkbox>

          <div
            class="text-base mr-2.5"
            :class="bp.enabled === false ? 'text-gray-400' : 'text-red-600'"
          >
            <i :class="bp.condition ? 'el-icon-s-flag' : 'el-icon-location-outline'"></i>
          </div>
          <div class="flex-1 overflow-hidden cursor-pointer">
            <div class="text-sm mb-1"
              :class="bp.enabled === false ? 'text-gray-400 line-through' : 'text-gray-800'"
            >
              {{ formatFileName(bp.file) }}:{{ bp.line }}
            </div>
            <div v-if="bp.condition" class="text-xs text-orange-600 mb-1">
              <i class="el-icon-warning-outline"></i> 条件: {{ bp.condition }}
            </div>
            <div v-if="bp.hitCondition" class="text-xs text-purple-600 mb-1">
              <i class="el-icon-data-line"></i> 命中: {{ bp.hitCondition }}
            </div>
            <div class="text-xs text-gray-500 whitespace-nowrap overflow-hidden text-ellipsis">
              {{ bp.file }}
            </div>
            <!-- 命中统计 -->
            <div v-if="bp.hitCount > 0" class="text-xs text-blue-600 mt-1">
              <i class="el-icon-aim"></i> 已命中 {{ bp.hitCount }} 次
            </div>
          </div>
          <div class="ml-2.5 flex items-center gap-2">
            <!-- 启用/禁用开关 -->
            <el-switch
              :value="bp.enabled !== false"
              @change="handleToggle(bp.id)"
              :width="36"
              active-color="#67C23A"
              inactive-color="#DCDFE6"
              title="启用/禁用断点"
              class="opacity-0 group-hover:opacity-100 transition-opacity"
            ></el-switch>
            <el-button
              type="text"
              icon="el-icon-edit"
              size="small"
              class="!text-gray-400 hover:!text-blue-600 opacity-0 group-hover:opacity-100 transition-opacity"
              :disabled="!canAddOrEdit"
              @click="handleEdit(bp)"
            ></el-button>
            <el-button
              type="text"
              icon="el-icon-delete"
              size="small"
              class="!text-gray-400 hover:!text-red-600 opacity-0 group-hover:opacity-100 transition-opacity"
              @click="handleRemove(bp.id)"
            ></el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- 添加/编辑断点对话框 -->
    <el-dialog
      :title="isEditMode ? '编辑断点' : '添加断点'"
      :visible.sync="dialogVisible"
      width="500px"
      :append-to-body="true"
    >
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        label-width="80px"
      >
        <el-form-item label="文件路径" prop="file">
          <el-select
            v-model="form.file"
            filterable
            placeholder="请选择或输入Go源文件路径"
            style="width: 100%"
            :loading="sourcesLoading"
          >
            <el-option
              v-for="source in sources"
              :key="source"
              :label="formatSourcePath(source)"
              :value="source"
            >
              <div class="source-option">
                <div class="source-option-main">{{ formatSourcePath(source) }}</div>
                <div class="source-option-full" :title="source">{{ source }}</div>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="行号" prop="line">
          <el-input-number
            v-model="form.line"
            :min="1"
            placeholder="请输入行号"
            style="width: 100%"
          ></el-input-number>
        </el-form-item>
        <el-form-item label="条件">
          <el-input
            v-model="form.condition"
            placeholder="可选，如：i > 100, err != nil"
            clearable
          >
            <template slot="prepend">if</template>
          </el-input>
          <div class="text-xs text-gray-500 mt-1">
            留空则为普通断点，设置条件后仅在条件为 true 时暂停
          </div>
        </el-form-item>
        <el-form-item label="命中次数">
          <el-select
            v-model="form.hitConditionType"
            style="width: 120px"
            @change="handleHitConditionTypeChange"
          >
            <el-option label="无限制" value=""></el-option>
            <el-option label="等于" value="=="></el-option>
            <el-option label="大于" value=">"></el-option>
            <el-option label="大于等于" value=">="></el-option>
            <el-option label="小于" value="<"></el-option>
            <el-option label="整除" value="%"></el-option>
          </el-select>
          <el-input-number
            v-if="form.hitConditionType"
            v-model="form.hitConditionValue"
            :min="1"
            placeholder="次数"
            style="width: 180px; margin-left: 10px"
          ></el-input-number>
          <div class="text-xs text-gray-500 mt-1">
            <span v-if="!form.hitConditionType">断点每次命中都会暂停</span>
            <span v-else-if="form.hitConditionType === '=='">第 {{ form.hitConditionValue }} 次命中时暂停</span>
            <span v-else-if="form.hitConditionType === '>'">命中次数大于 {{ form.hitConditionValue }} 次时暂停</span>
            <span v-else-if="form.hitConditionType === '>='">命中次数大于等于 {{ form.hitConditionValue }} 次时暂停</span>
            <span v-else-if="form.hitConditionType === '<'">命中次数小于 {{ form.hitConditionValue }} 次时暂停</span>
            <span v-else-if="form.hitConditionType === '%'">每 {{ form.hitConditionValue }} 次命中时暂停一次</span>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'BreakpointPanel',
  props: {
    breakpoints: {
      type: Array,
      default: () => []
    },
    debuggerState: {
      type: String,
      default: 'stopped'
    },
    sources: {
      type: Array,
      default: () => []
    },
    sourcesLoading: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: false,
      isEditMode: false,
      editingBreakpointId: null,
      form: {
        file: '',
        line: 1,
        condition: '',
        hitConditionType: '',
        hitConditionValue: 1
      },
      rules: {
        file: [
          { required: true, message: '请选择或输入文件路径', trigger: 'change' }
        ],
        line: [
          { required: true, message: '请输入行号', trigger: 'blur' },
          { type: 'number', min: 1, message: '行号必须大于0', trigger: 'blur' }
        ]
      },
      // 批量操作相关
      selectedBreakpoints: [], // 选中的断点ID列表
      checkAll: false, // 全选状态
      // 搜索和过滤相关
      searchKeyword: '', // 搜索关键字
      filterEnabled: 'all', // 过滤条件：all | enabled | disabled
      // 分组相关
      viewMode: 'grouped', // 视图模式：grouped | list
      expandedGroups: {} // 展开的分组，key为文件路径，value为true/false
    }
  },
  mounted() {
    // 从 localStorage 恢复视图模式
    const savedViewMode = localStorage.getItem('breakpoint-view-mode')
    if (savedViewMode === 'list' || savedViewMode === 'grouped') {
      this.viewMode = savedViewMode
    }
  },
  watch: {
    // 监听视图模式变化，保存到 localStorage
    viewMode(newMode) {
      localStorage.setItem('breakpoint-view-mode', newMode)
    }
  },
  computed: {
    // 是否可以添加/编辑断点（只有 paused 和 running 状态才允许）
    canAddOrEdit() {
      return this.debuggerState === 'paused' || this.debuggerState === 'running'
    },
    // 全选框的半选状态
    isIndeterminate() {
      const selectedCount = this.selectedBreakpoints.length
      const totalCount = this.breakpoints.length
      return selectedCount > 0 && selectedCount < totalCount
    },
    // 过滤后的断点列表
    filteredBreakpoints() {
      let filtered = this.breakpoints

      // 根据启用状态过滤
      if (this.filterEnabled === 'enabled') {
        filtered = filtered.filter(bp => bp.enabled !== false)
      } else if (this.filterEnabled === 'disabled') {
        filtered = filtered.filter(bp => bp.enabled === false)
      }

      // 根据搜索关键字过滤
      if (this.searchKeyword && this.searchKeyword.trim()) {
        const keyword = this.searchKeyword.trim().toLowerCase()
        filtered = filtered.filter(bp => {
          // 搜索文件路径
          if (bp.file && bp.file.toLowerCase().includes(keyword)) {
            return true
          }
          // 搜索行号
          if (bp.line && bp.line.toString().includes(keyword)) {
            return true
          }
          // 搜索条件
          if (bp.condition && bp.condition.toLowerCase().includes(keyword)) {
            return true
          }
          // 搜索命中条件
          if (bp.hitCondition && bp.hitCondition.toLowerCase().includes(keyword)) {
            return true
          }
          return false
        })
      }

      return filtered
    },
    // 分组后的断点列表
    groupedBreakpoints() {
      const groups = {}

      // 将过滤后的断点按文件分组
      this.filteredBreakpoints.forEach(bp => {
        if (!groups[bp.file]) {
          groups[bp.file] = {
            file: bp.file,
            breakpoints: [],
            total: 0,
            enabled: 0,
            disabled: 0
          }
        }

        groups[bp.file].breakpoints.push(bp)
        groups[bp.file].total++

        if (bp.enabled !== false) {
          groups[bp.file].enabled++
        } else {
          groups[bp.file].disabled++
        }
      })

      // 转换为数组并按文件名排序
      return Object.values(groups).sort((a, b) => {
        const fileA = this.formatFileName(a.file).toLowerCase()
        const fileB = this.formatFileName(b.file).toLowerCase()
        return fileA.localeCompare(fileB)
      })
    }
  },
  methods: {
    showAddDialog() {
      this.isEditMode = false
      this.editingBreakpointId = null
      this.form = {
        file: '',
        line: 1,
        condition: '',
        hitConditionType: '',
        hitConditionValue: 1
      }
      this.dialogVisible = true
    },

    handleEdit(breakpoint) {
      this.isEditMode = true
      this.editingBreakpointId = breakpoint.id

      // 解析 hitCondition 字符串
      let hitConditionType = ''
      let hitConditionValue = 1

      if (breakpoint.hitCondition) {
        const hitCond = breakpoint.hitCondition.trim()
        // 解析不同格式: "% 10 == 0", "> 5", ">= 10", "== 5", "< 10"
        if (hitCond.startsWith('%')) {
          hitConditionType = '%'
          const match = hitCond.match(/% (\d+)/)
          if (match) {
            hitConditionValue = parseInt(match[1])
          }
        } else if (hitCond.startsWith('>=')) {
          hitConditionType = '>='
          const match = hitCond.match(/>= (\d+)/)
          if (match) {
            hitConditionValue = parseInt(match[1])
          }
        } else if (hitCond.startsWith('>')) {
          hitConditionType = '>'
          const match = hitCond.match(/> (\d+)/)
          if (match) {
            hitConditionValue = parseInt(match[1])
          }
        } else if (hitCond.startsWith('==')) {
          hitConditionType = '=='
          const match = hitCond.match(/== (\d+)/)
          if (match) {
            hitConditionValue = parseInt(match[1])
          }
        } else if (hitCond.startsWith('<')) {
          hitConditionType = '<'
          const match = hitCond.match(/< (\d+)/)
          if (match) {
            hitConditionValue = parseInt(match[1])
          }
        }
      }

      this.form = {
        file: breakpoint.file,
        line: breakpoint.line,
        condition: breakpoint.condition || '',
        hitConditionType: hitConditionType,
        hitConditionValue: hitConditionValue
      }
      this.dialogVisible = true
    },

    handleHitConditionTypeChange() {
      // 当命中类型改变时，重置值为1
      if (!this.form.hitConditionValue || this.form.hitConditionValue < 1) {
        this.form.hitConditionValue = 1
      }
    },

    handleSubmit() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          // 构建命中条件字符串
          let hitCondition = null
          if (this.form.hitConditionType) {
            // 验证命中次数值
            const hitValue = this.form.hitConditionValue
            if (!hitValue || hitValue < 1 || !Number.isInteger(hitValue)) {
              this.$message.error('命中次数必须是大于 0 的整数')
              return
            }

            if (this.form.hitConditionType === '%') {
              // 整除条件：% n == 0
              hitCondition = `% ${hitValue} == 0`
            } else {
              // 其他比较条件：> n, >= n, == n, < n
              hitCondition = `${this.form.hitConditionType} ${hitValue}`
            }
          }

          const breakpointData = {
            file: this.form.file,
            line: this.form.line,
            condition: this.form.condition || null,
            hitCondition: hitCondition
          }

          if (this.isEditMode) {
            // 编辑模式：发送编辑事件
            this.$emit('edit', {
              id: this.editingBreakpointId,
              ...breakpointData
            })
          } else {
            // 添加模式：发送添加事件
            this.$emit('add', breakpointData)
          }

          this.dialogVisible = false
        }
      })
    },

    handleRemove(id) {
      this.$confirm('确定要删除这个断点吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$emit('remove', id)
      }).catch(() => {})
    },

    handleToggle(id) {
      this.$emit('toggle', id)
    },

    formatFileName(filePath) {
      if (!filePath) return ''
      const parts = filePath.split(/[/\\]/)
      return parts[parts.length - 1]
    },

    formatSourcePath(filePath) {
      if (!filePath) return ''
      const parts = filePath.split(/[/\\]/)
      // 显示最后3段路径
      if (parts.length > 3) {
        return '.../' + parts.slice(-3).join('/')
      }
      return parts.join('/')
    },

    // 批量操作相关方法

    // 全选/取消全选
    handleCheckAllChange(val) {
      if (val) {
        // 全选：选中所有断点
        this.selectedBreakpoints = this.breakpoints.map(bp => bp.id)
      } else {
        // 取消全选
        this.selectedBreakpoints = []
      }
    },

    // 单个断点选择变化
    handleSelectChange(id, checked) {
      if (checked) {
        // 添加到选中列表
        if (!this.selectedBreakpoints.includes(id)) {
          this.selectedBreakpoints.push(id)
        }
      } else {
        // 从选中列表移除
        this.selectedBreakpoints = this.selectedBreakpoints.filter(bpId => bpId !== id)
      }

      // 更新全选状态
      this.checkAll = this.selectedBreakpoints.length === this.breakpoints.length
    },

    // 批量操作命令处理
    handleBatchCommand(command) {
      if (this.selectedBreakpoints.length === 0) {
        this.$message.warning('请先选择断点')
        return
      }

      switch (command) {
        case 'enable':
          this.handleBatchEnable()
          break
        case 'disable':
          this.handleBatchDisable()
          break
        case 'delete':
          this.handleBatchDelete()
          break
      }
    },

    // 批量启用
    handleBatchEnable() {
      const count = this.selectedBreakpoints.length
      this.$confirm(`确定要启用选中的 ${count} 个断点吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        // 发送批量启用事件
        this.$emit('batch-toggle', {
          ids: [...this.selectedBreakpoints],
          enabled: true
        })
        // 清空选择
        this.selectedBreakpoints = []
        this.checkAll = false
      }).catch(() => {})
    },

    // 批量禁用
    handleBatchDisable() {
      const count = this.selectedBreakpoints.length
      this.$confirm(`确定要禁用选中的 ${count} 个断点吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 发送批量禁用事件
        this.$emit('batch-toggle', {
          ids: [...this.selectedBreakpoints],
          enabled: false
        })
        // 清空选择
        this.selectedBreakpoints = []
        this.checkAll = false
      }).catch(() => {})
    },

    // 批量删除
    handleBatchDelete() {
      const count = this.selectedBreakpoints.length
      this.$confirm(`确定要删除选中的 ${count} 个断点吗？此操作不可恢复。`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 发送批量删除事件
        this.$emit('batch-remove', [...this.selectedBreakpoints])
        // 清空选择
        this.selectedBreakpoints = []
        this.checkAll = false
      }).catch(() => {})
    },

    // 导入/导出相关方法

    // 处理"更多"下拉菜单命令
    handleMoreCommand(command) {
      switch (command) {
        case 'export':
          this.handleExportBreakpoints()
          break
        case 'import':
          this.handleImportBreakpoints()
          break
      }
    },

    // 导出断点
    handleExportBreakpoints() {
      if (this.breakpoints.length === 0) {
        this.$message.warning('没有可导出的断点')
        return
      }

      try {
        // 准备导出数据（移除 dlvId 和选择状态，只保留用户定义的断点信息）
        const exportData = {
          version: '1.0',
          exportTime: new Date().toISOString(),
          breakpoints: this.breakpoints.map(bp => ({
            file: bp.file,
            line: bp.line,
            condition: bp.condition || null,
            hitCondition: bp.hitCondition || null,
            enabled: bp.enabled !== false
          }))
        }

        // 转换为 JSON 字符串
        const jsonString = JSON.stringify(exportData, null, 2)

        // 创建 Blob 并下载
        const blob = new Blob([jsonString], { type: 'application/json' })
        const url = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = url

        // 生成文件名：breakpoints-YYYYMMDD-HHmmss.json
        const now = new Date()
        const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '')
        const timeStr = now.toTimeString().slice(0, 8).replace(/:/g, '')
        link.download = `breakpoints-${dateStr}-${timeStr}.json`

        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(url)

        this.$message.success(`成功导出 ${this.breakpoints.length} 个断点`)
      } catch (error) {
        console.error('导出断点失败:', error)
        this.$message.error('导出失败：' + error.message)
      }
    },

    // 导入断点（触发文件选择）
    handleImportBreakpoints() {
      this.$refs.fileInput.click()
    },

    // 文件选择变化
    handleFileChange(event) {
      const file = event.target.files[0]
      if (!file) return

      // 检查文件类型
      if (!file.name.endsWith('.json')) {
        this.$message.error('请选择 JSON 格式的断点文件')
        event.target.value = '' // 清空选择
        return
      }

      const reader = new FileReader()

      reader.onload = (e) => {
        try {
          const content = e.target.result
          const data = JSON.parse(content)

          // 验证数据格式
          if (!data.breakpoints || !Array.isArray(data.breakpoints)) {
            this.$message.error('断点文件格式错误：缺少 breakpoints 数组')
            return
          }

          // 验证每个断点的必需字段
          const validBreakpoints = data.breakpoints.filter(bp => {
            return bp.file && typeof bp.line === 'number' && bp.line > 0
          })

          if (validBreakpoints.length === 0) {
            this.$message.error('断点文件中没有有效的断点')
            return
          }

          // 确认导入
          this.$confirm(
            `将导入 ${validBreakpoints.length} 个断点。${this.breakpoints.length > 0 ? '现有断点将被保留。' : ''}`,
            '确认导入',
            {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'info'
            }
          ).then(() => {
            // 发送导入事件到父组件
            this.$emit('import', validBreakpoints)
          }).catch(() => {})
        } catch (error) {
          console.error('解析断点文件失败:', error)
          this.$message.error('解析文件失败：' + error.message)
        } finally {
          // 清空文件选择，允许重复选择同一文件
          event.target.value = ''
        }
      }

      reader.onerror = () => {
        this.$message.error('读取文件失败')
        event.target.value = ''
      }

      reader.readAsText(file)
    },

    // 分组相关方法

    // 切换分组展开/折叠状态
    toggleGroup(file) {
      this.$set(this.expandedGroups, file, !this.expandedGroups[file])
    },

    // 检查分组是否展开
    isGroupExpanded(file) {
      // 默认展开所有分组
      return this.expandedGroups[file] !== false
    },

    // 处理分组级别命令
    handleGroupCommand(command, group) {
      const breakpointIds = group.breakpoints.map(bp => bp.id)

      switch (command) {
        case 'enable-all':
          this.handleGroupEnableAll(group, breakpointIds)
          break
        case 'disable-all':
          this.handleGroupDisableAll(group, breakpointIds)
          break
        case 'delete-all':
          this.handleGroupDeleteAll(group, breakpointIds)
          break
      }
    },

    // 启用分组内所有断点
    handleGroupEnableAll(group, breakpointIds) {
      const fileName = this.formatFileName(group.file)
      this.$confirm(`确定要启用 "${fileName}" 中的所有 ${group.total} 个断点吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        this.$emit('batch-toggle', {
          ids: breakpointIds,
          enabled: true
        })
      }).catch(() => {})
    },

    // 禁用分组内所有断点
    handleGroupDisableAll(group, breakpointIds) {
      const fileName = this.formatFileName(group.file)
      this.$confirm(`确定要禁用 "${fileName}" 中的所有 ${group.total} 个断点吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$emit('batch-toggle', {
          ids: breakpointIds,
          enabled: false
        })
      }).catch(() => {})
    },

    // 删除分组内所有断点
    handleGroupDeleteAll(group, breakpointIds) {
      const fileName = this.formatFileName(group.file)
      this.$confirm(
        `确定要删除 "${fileName}" 中的所有 ${group.total} 个断点吗？此操作不可恢复。`,
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        this.$emit('batch-remove', breakpointIds)
      }).catch(() => {})
    }
  }
}
</script>

<style scoped>
/* 源文件选项样式 */
.source-option {
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
  width: 100%;
}

.source-option-main {
  font-size: 14px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.source-option-full {
  font-size: 12px;
  color: #8492a6;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 批量选择复选框样式 - 增强辨识度 */
.batch-checkbox >>> .el-checkbox__inner {
  border: 2px solid #909399;
  border-radius: 2px;
  background-color: #f5f7fa;
}

.batch-checkbox >>> .el-checkbox__input.is-checked .el-checkbox__inner {
  background-color: #409EFF;
  border-color: #409EFF;
}

.batch-checkbox >>> .el-checkbox__inner:hover {
  border-color: #409EFF;
}

/* Switch 样式微调 */
.el-switch {
  display: inline-flex;
  align-items: center;
  height: 20px;
}
</style>
